﻿using System;
using System.ServiceModel;
using System.Collections.Generic;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using SSSToolbox;
using System.Text;

namespace SSSToolbox
{
    class LogHandler
    {
        public string BuildErrorString(Exception e)
        {
            StringBuilder errormessage = new StringBuilder(DateTime.Now.ToString());
            errormessage.Append(": ");
            errormessage.Append(e.Message);
            errormessage.Append(Environment.NewLine);
            errormessage.Append(e.InnerException);
            errormessage.Append(Environment.NewLine);
            errormessage.Append(Environment.NewLine);
            return errormessage.ToString();
        }

        public Entity GetGlobalLog(IOrganizationService service)
        {
            EntityCollection GlobalLog;
            QueryByAttribute query = new QueryByAttribute("crmtb_profilerlog") { ColumnSet = new ColumnSet("crmtb_log", "crmtb_globallog") };
            query.Attributes.AddRange("crmtb_globallog");
            query.Values.AddRange(true);
            GlobalLog = service.RetrieveMultiple(query);

            //Keeping this as greater than 0 to account for scenarios where two threads might create the global record before either transaction finishes...
            if (GlobalLog.Entities.Count > 0)
            {
                return GlobalLog[0];
            }
            else
            {
                CreateGlobalLog(service);
                return GetGlobalLog(service);
            }
        }

        public void CreateGlobalLog(IOrganizationService service)
        {
            Entity gblLog = new Entity("crmtb_profilerlog");
            gblLog["crmtb_globallog"] = true;
            gblLog["crmtb_name"] = "Global Profiler Log";
            service.Create(gblLog);
        }

        public void LogError(Entity logrecord, IOrganizationService service, string error)
        {
            string combinederrors;

            if (logrecord.Attributes.Contains("crmtb_log"))
            {
                combinederrors = AppendErrors((string)logrecord["crmtb_log"], error);
            }
            else
            {
                combinederrors = AppendErrors("", error);
            }
            logrecord["crmtb_log"] = combinederrors;
            service.Update(logrecord);
        }

        public string AppendErrors(string baseerror, string error)
        {
            StringBuilder combinederrors = new StringBuilder(baseerror);
            combinederrors.Append(Environment.NewLine);
            combinederrors.Append(error);
            return combinederrors.ToString();
        }

        public Guid GetProfilerLogId(IOrganizationService service, Entity profiler)
        {
            if (profiler.Attributes.Contains("crmtb_enabledebuglogging") && (bool)profiler["crmtb_enabledebuglogging"])
            {
                EntityCollection ProfilerLogs;
                QueryByAttribute query = new QueryByAttribute("crmtb_profilerlog") { ColumnSet = new ColumnSet() };
                query.Attributes.AddRange("crmtb_profilerid");
                query.Values.AddRange(profiler.Id);
                ProfilerLogs = service.RetrieveMultiple(query);

                if (ProfilerLogs.Entities.Count > 0)
                {
                    return ProfilerLogs[0].Id;
                }
                else
                {
                    Guid profilerlogId = CreateProfilerLog(service, profiler);
                    return profilerlogId;
                }

            }
            else
            {
                return Guid.Empty;
            }
        }

        public Guid CreateProfilerLog(IOrganizationService service, Entity profiler)
        {
            Entity ProfilerLog = new Entity("crmtb_profilerlog");
            ProfilerLog["crmtb_profilerid"] = new EntityReference("crmtb_profiler", profiler.Id);
            ProfilerLog["crmtb_name"] = profiler["crmtb_name"];
            Guid profilerid = service.Create(ProfilerLog);
            return profilerid;
        }
    }
}
